package com.xzl.xep.dao.hibernate;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;

import javax.persistence.Entity;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Repository;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.SessionFactory;

import com.xzl.xep.dao.BaseDao;
 
  

@SuppressWarnings("unchecked")
@Repository("baseDao")
public class HibernateDao implements BaseDao{

	@Autowired
	@Qualifier("sessionFactory")
	private SessionFactory sessionFactory;

	public Session getSession() { 
		return sessionFactory.getCurrentSession();
	}
	
	public <T> T  saveObject(T object){
	
		getSession().save(object);
		return object;
	}

	public <T> T  saveOrUpdateObject(T object){
		
		getSession().saveOrUpdate(object);
		return object;
	}


	public <T> T  updateObject(T object) {
		getSession().update(object);
		return object;
	}


	public  <T> void delObject(T object) {
		getSession().delete(object);
	}

	
	
	public  <T> T loadObject(Class<T> clazz, Serializable id) {
		return (T) getSession().get(clazz, id);
	}


	
	public  <T> List<T> selectByHql(String hql) {
		return getSession().createQuery(hql).list();
	}
	
	public <T> List<T> selectByHql(String hql,Integer first,Integer max) {
		return getSession().createQuery(hql).setFirstResult(first).setMaxResults(max).list();
	}
	

	public <T> List<T> selectBySql(String sql) {
		// TODO Auto-generated method stub
		return getSession().createSQLQuery(sql).list();
	}
	
	public <T> T selectOneBySql(String sql,Class<?> claz) {
		List<T> l = selectBySql(sql,claz);
		if(l.size() == 1) return l.get(0);
		else return null;
	}
	
	public <T> List<T> selectBySql(String sql,Class<?> claz) {
		// TODO Auto-generated method stub
		SQLQuery query = getSession().createSQLQuery(sql);
		if(claz.isAnnotationPresent(Entity.class)){
			query.addEntity(claz);
		}else{
			query.setResultTransformer(new EscResultToBean(claz));
		}
		
		return query.list();
	}
	

	public <T> List<T> selectBySql(String sql,int first,int max,Class<?> claz) {
		// TODO Auto-generated method stub
		SQLQuery query = getSession().createSQLQuery(sql);
		if(claz.isAnnotationPresent(Entity.class)){
			query.addEntity(claz);
		}else{
			query.setResultTransformer(new EscResultToBean(claz));
		}
		
		return query.setFirstResult(first).setMaxResults(max).list();
	}


	public <T> List<T> selectBySql(String sql,int first,int max) {
		// TODO Auto-generated method stub
		return getSession().createSQLQuery(sql).setFirstResult(first).setMaxResults(max).list();
	}
	

	public int executeByHql(String hql) {
		// TODO Auto-generated method stub
		return getSession().createQuery(hql).executeUpdate();
	}
	

	public int executeBySql(String sql) {
		// TODO Auto-generated method stub
		return getSession().createSQLQuery(sql).executeUpdate();
	}

	public <T> T selectOneByHql(String hql) {
		// TODO Auto-generated method stub
		List<T> l = selectByHql(hql);
		if(l.size() == 1) return l.get(0);
		else return null;
	}

	public <T> void saveCollection(Collection<T> collection) {
		// TODO Auto-generated method stub
		for(T object : collection){
			this.saveOrUpdateObject(object);
		}
	}

	@Override
	public Integer selectIntByHql(String hql) {
		// TODO Auto-generated method stub
		Object result =  getSession().createQuery(hql).uniqueResult();
		
		if(result instanceof Long)
			return ((Long)result).intValue();

					
		return (Integer) result;
	}

	@Override
	public Double selectDoubleByHql(String hql) {
		// TODO Auto-generated method stub
		return (Double) getSession().createQuery(hql).uniqueResult();
	}

	@Override
	public Integer selectIntBySql(String sql) {
		// TODO Auto-generated method stub
		
		Object result =  getSession().createSQLQuery(sql).uniqueResult();
		
		if(result instanceof Long)
			return ((Long)result).intValue();

					
		return (Integer) result;
	}
	
	
}
